package mobileann.mafamily.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import mobileann.mafamily.act.main.FS;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.DisplayMetrics;

import com.mobileann.mafamily.R;
import com.mofind.android.utils.BitmapUtils;

/**
 * 主要功能:
 * <br> 这是背景,程序提供的三张图片
 * 
 * @annotation ADRIAN.2015.8.4.11.02
 */
public class WallPaperUtils {
	public final static int TYPE_ID = 0;
	public final static int TYPE_PATH = 1;
	public final static int[] WallPaperIds = {R.drawable.bg_pull_lock3,R.drawable.bg_pull_lock1,R.drawable.bg_lock};

	public static void restoreImages(){
		int type = SPUtils.getWallPaperType();
		switch (type) {
		case TYPE_ID:
			int id = WallPaperIds[SPUtils.getWallPaperPosition()];
			storeImages(FS.getInstance(), id);
			break;
		case TYPE_PATH:
			String path = SPUtils.getWallPaperPath();
			if(!TextUtils.isEmpty(path)){
				storeImages(FS.getInstance(), path);
			}else{
				int id2 = WallPaperIds[SPUtils.getWallPaperPosition()];
				storeImages(FS.getInstance(), id2);
			}
			break;
		default:
			break;
		}
	}

	//删除旧图片
	public static void removeImageFiles(){
		String blurImageName = getBlurImageName();
		String bgImageName = getBgImageName();
		File bg = new File(bgImageName);
		File blur = new File(blurImageName);
		if(bg.exists()){
			bg.delete();
		}
		if(blur.exists()){
			blur.delete();
		}
	}

	/**
	 * 主要功能:
	 * <br>1.按ID存储所有图片
	 * <br>2. 开启线程进行储存相片
	 * @param c   上下文
	 * @param id  选择第几张图片
	 * @annotation ADRIAN.2015.8.4.11.38
	 */
	public static void storeImages(final Context c, final int id){
		// 这里报的是空指针异常,初步判断是id错误,但不确定 &ADRIAN.2015.8.4.15.44
		final String blurImageName = getBlurImageName();
		final String bgImageName = getBgImageName();
		final File blurredImage = new File(blurImageName);
		final File bgImage = new File(bgImageName);
		if (!blurredImage.exists()||!bgImage.exists()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// No image found => let's generate it!
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					Bitmap image = BitmapFactory.decodeResource(c.getResources(), id, options);
					storeImage(image, bgImage);
					Bitmap newImg = fastBlur(FS.getInstance(), image, 16);
					storeImage(newImg, blurredImage);
					image.recycle();
					newImg.recycle();
					image = null;
					newImg = null;
				}
			}).start();
		}
	}

	//按ID存储背景图片
	public static void storeBgImage(final Context c, final int id){
		final String bgImageName = getBgImageName();
		final File bgImage = new File(bgImageName);
		if (!bgImage.exists()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// No image found => let's generate it!
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					Bitmap image = BitmapFactory.decodeResource(c.getResources(), id, options);
					storeImage(image, bgImage);
					image.recycle();
					image = null;
				}
			}).start();
		}
	}

	//按路径存储所有图片
	public static void storeImages(final Context c, final String FilePath){
		final String blurImageName = getBlurImageName();
		final String bgImageName = getBgImageName();
		final File blurredImage = new File(blurImageName);
		final File bgImage = new File(bgImageName);
		if (!blurredImage.exists()||!bgImage.exists()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// No image found => let's generate it!
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					Bitmap image = BitmapFactory.decodeFile(FilePath, options);
					storeImage(image, bgImage);
					if(image!=null){
						Bitmap newImg = fastBlur(FS.getInstance(), image, 16);
						storeImage(newImg, blurredImage);
						newImg.recycle();
						newImg = null;
					}
					image.recycle();
					image = null;

				}
			}).start();
		}
	}

	//按路径存储背景图片
	public static void storeBgImage(final Context c, final String FilePath){
		final String bgImageName = getBgImageName();
		final File bgImage = new File(bgImageName);
		if (!bgImage.exists()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// No image found => let's generate it!
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					Bitmap image = BitmapFactory.decodeFile(FilePath, options);
					storeImage(image, bgImage);
					image.recycle();
					image = null;
				}
			}).start();
		}
	}

	//存储虚化图片
	public static void storeBlurImage(final Context c){
		final String blurImageName = getBlurImageName();
		final String bgImageName = getBgImageName();
		final File blurredImage = new File(blurImageName);
		if (!blurredImage.exists()) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					// No image found => let's generate it!
					BitmapFactory.Options options = new BitmapFactory.Options();
					options.inSampleSize = 2;
					Bitmap image = BitmapFactory.decodeFile(bgImageName, options);
					Bitmap newImg = fastBlur(FS.getInstance(), image, 16);
					storeImage(newImg, blurredImage);
					image.recycle();
					newImg.recycle();
					image = null;
					newImg = null;
				}
			}).start();
		}
	}

	//	public static boolean blurImageExist(){
	//		String blurImageName = getBlurImageName();
	//		File blurredImage = new File(blurImageName);
	//		return blurredImage.exists();
	//	}
	//	public static boolean bgImageExist(){
	//		String bgImageName = getBgImageName();
	//		File bgImage = new File(bgImageName);
	//		return bgImage.exists();
	//	}

	//	public static void storeImages(final Context c){
	//		final String blurImageName = getBlurImageName();
	//		final String bgImageName = getBgImageName();
	//		final File blurredImage = new File(blurImageName);
	//		final File bgImage = new File(bgImageName);
	//		if (!blurredImage.exists()) {
	//			new Thread(new Runnable() {
	//				@Override
	//				public void run() {
	//					// No image found => let's generate it!
	//					BitmapFactory.Options options = new BitmapFactory.Options();
	//					options.inSampleSize = 2;
	//					Bitmap image = BitmapFactory.decodeFile(bgImageName, options);
	//					storeImage(image, bgImage);
	//					Bitmap newImg = fastBlur(FS.getInstance(), image, 16);
	//					storeImage(newImg, blurredImage);
	//				}
	//			}).start();
	//		}
	//	}

	//获取背景图片
	public static Drawable getBgImage(){
		String fileName = getBgImageName();
		//		int screenWidth = 720;
		DisplayMetrics metric = new DisplayMetrics(); 
		metric=FS.getInstance().getResources().getDisplayMetrics();
		int screenWidth = metric.widthPixels;     // 屏幕宽度（像素）  
		//		int height = metric.heightPixels;   // 屏幕高度（像素）
		Bitmap temp = null;
		temp = BitmapFactory.decodeFile(fileName);
		//TODO 如果加载本地图片为空,则加载本地resource文件 &ADRIAN.2015.8.5.10.58
		if (temp == null) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 2;
			temp = BitmapFactory.decodeResource(FS.getInstance().getResources(), WallPaperIds[SPUtils.getWallPaperPosition()], options);
		}
		Bitmap bmpBlurred = Bitmap.createScaledBitmap(temp, screenWidth, (int) (temp.getHeight()
				* ((float) screenWidth) / (float) temp.getWidth()), false);
		Drawable blurDra = BitmapUtils.bitmap2DrawableByBD(bmpBlurred);
		if (!temp.equals(bmpBlurred)) {
			temp.recycle();
			temp = null;
		}
		return blurDra;
	}

	//	private static Object getWindowManager() {
	//		// TODO Auto-generated method stub
	//		return null;
	//	}

	//获取模糊图片
	public static Drawable getBlurImage(){
		// TODO 增加健壮性
		String fileName = getBlurImageName();
		//		int screenWidth = 720;
		DisplayMetrics metric = new DisplayMetrics(); 
		metric=FS.getInstance().getResources().getDisplayMetrics();
		int screenWidth = metric.widthPixels;     // 屏幕宽度（像素）  
		Bitmap temp = null;
		temp = BitmapFactory.decodeFile(fileName);
		Bitmap image = null;
		// 增加,如果获取到的图像为null,怎使用本地的图片进行虚化后的图片  &ADRIAN.2015.8.5.12.31
		if (temp == null) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 2;
			image = BitmapFactory.decodeResource(FS.getInstance().getResources(), WallPaperIds[SPUtils.getWallPaperPosition()], options);
			temp = fastBlur(FS.getInstance(), image, 16);
			image.recycle();
			image = null;
		}
		Bitmap bmpBlurred = Bitmap.createScaledBitmap(temp, screenWidth, (int) (temp.getHeight()
				* ((float) screenWidth) / (float) temp.getWidth()), false);
		Drawable blurDra = BitmapUtils.bitmap2DrawableByBD(bmpBlurred); 
		if (!temp.equals(bmpBlurred)) {
			temp.recycle();
			temp = null;
		}
		return blurDra;
	}

	/*
	 * 主要功能:
	 * <br>获取模糊图片名
	 * <br> 如果没有MAFamilySafe文件夹,则创建
	 */
	private static String getBlurImageName(){
		String dirName = FS.getInstance().getParentPath() + File.separator + "lock_bg";
		File dir = new File(dirName);
		if (!dir.exists())
			dir.mkdir();
		String date = SPUtils.getImageDate();
		String fileName = dirName + File.separator + "blur_" + date + ".png";
		return fileName;
	}

	/*
	 * 主要功能:
	 * <br>获取背景图片名
	 * <br>将原始的图片也存到本地
	 */
	private static String getBgImageName(){
		//		String dirName = FS.getInstance().getParentPath() + File.separator + "lock_bg";
		StringBuffer dirName = new StringBuffer(64);
		dirName.append(FS.getInstance().getParentPath());
		dirName.append(File.separator);
		dirName.append("lock_bg");
		File dir = new File(dirName.toString());
		if (!dir.exists())
			dir.mkdir();
		String date = SPUtils.getImageDate();
		//		String fileName = dirName + File.separator + "bg_" + date + ".png";
		StringBuffer fileName = new StringBuffer(64);
		fileName.append(dirName);
		fileName.append(File.separator);
		fileName.append("bg_");
		fileName.append(date);
		fileName.append(".png");
		return fileName.toString();
	}

	public static void setImageDate(){
		DateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss",Locale.getDefault());
		String date = formatter.format(new Date());
		SPUtils.setImageDate(date);
	}

	//	public static Drawable getBlurImage(int id){
	//		String fileName = getFileName(id);
	//		int screenWidth = 720;
	//		Bitmap temp = BitmapFactory.decodeFile(fileName);
	//		Bitmap bmpBlurred = Bitmap.createScaledBitmap(temp, screenWidth, (int) (temp.getHeight()
	//				* ((float) screenWidth) / (float) temp.getWidth()), false);
	//		Drawable blurDra = BitmapUtils.bitmap2DrawableByBD(bmpBlurred);
	//		return blurDra;
	//	}
	//	
	//	public static void saveBlurImage(final Context c, final int id){
	//		String fileName = WallPaperUtils.getFileName(id);
	//		final File blurredImage = new File(fileName);
	//		if (!blurredImage.exists()) {
	//			new Thread(new Runnable() {
	//				@Override
	//				public void run() {
	//					// No image found => let's generate it!
	//					BitmapFactory.Options options = new BitmapFactory.Options();
	//					options.inSampleSize = 2;
	//					Bitmap image = BitmapFactory.decodeResource(c.getResources(), id, options);
	//					Bitmap newImg = WallPaperUtils.fastBlur(FS.getInstance(), image, 16);
	//					WallPaperUtils.storeImage(newImg, blurredImage);
	//				}
	//			}).start();
	//		}
	//	}
	//	
	//	private static String getFileName(int id){
	//		String dirName = FS.getInstance().getParentPath() + File.separator + "lock_bg";
	//		File dir = new File(dirName);
	//		if (!dir.exists())
	//			dir.mkdir();
	//		String fileName = dirName + File.separator + id + ".png";
	//		return fileName;
	//	}

	/**
	 * 将图片存在本地
	 * 
	 * @param image
	 *            the image to store.
	 * @param pictureFile
	 *            the file in which it must be stored
	 */
	private static void storeImage(Bitmap image, File pictureFile) {
		if (pictureFile == null) {
			return;
		}
		try {
			FileOutputStream fos = new FileOutputStream(pictureFile);
			image.compress(Bitmap.CompressFormat.PNG, 50, fos);
			fos.close();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
	}

//	private static void test(String path){
//		BitmapFactory.Options bfOptions = new BitmapFactory.Options();
//		bfOptions.inDither=false;
//		bfOptions.inPurgeable=true;
//		bfOptions.inTempStorage=new byte[12 * 1024];
//		// bfOptions.inJustDecodeBounds = true;
//		File file = new File(path);
//		FileInputStream fs=null;
//		try {
//			fs = new FileInputStream(file);
//		} catch (FileNotFoundException e) {
//			e.printStackTrace();
//		}
//		Bitmap bmp = null;
//		if(fs != null){
//			try {
//				bmp = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
//			} catch (IOException e) {
//				e.printStackTrace();
//			}finally{
//				if(fs!=null) {
//					try {
//						fs.close();
//					} catch (IOException e) {
//						e.printStackTrace();
//					}
//				}
//			}
//		}
//	}

	//快速虚化
	private static Bitmap fastBlur(Context context, Bitmap sentBitmap, int radius) {
		// 先复制一下图片 &ADRIAN.2015.8.4.12.10
		Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
		if (radius < 1) {
			return (null);
		}
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		int[] pix = new int[w * h];
		bitmap.getPixels(pix, 0, w, 0, 0, w, h);

		int wm = w - 1;
		int hm = h - 1;
		int wh = w * h;
		int div = radius + radius + 1;

		int r[] = new int[wh];
		int g[] = new int[wh];
		int b[] = new int[wh];
		int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
		int vmin[] = new int[Math.max(w, h)];

		int divsum = (div + 1) >> 1;
		divsum *= divsum;
		int dv[] = new int[256 * divsum];
		for (i = 0; i < 256 * divsum; i++) {
			dv[i] = (i / divsum);
		}

		yw = yi = 0;

		int[][] stack = new int[div][3];
		int stackpointer;
		int stackstart;
		int[] sir;
		int rbs;
		int r1 = radius + 1;
		int routsum, goutsum, boutsum;
		int rinsum, ginsum, binsum;

		for (y = 0; y < h; y++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			for (i = -radius; i <= radius; i++) {
				p = pix[yi + Math.min(wm, Math.max(i, 0))];
				sir = stack[i + radius];
				sir[0] = (p & 0xff0000) >> 16;
			sir[1] = (p & 0x00ff00) >> 8;
		sir[2] = (p & 0x0000ff);
		rbs = r1 - Math.abs(i);
		rsum += sir[0] * rbs;
		gsum += sir[1] * rbs;
		bsum += sir[2] * rbs;
		if (i > 0) {
			rinsum += sir[0];
			ginsum += sir[1];
			binsum += sir[2];
		} else {
			routsum += sir[0];
			goutsum += sir[1];
			boutsum += sir[2];
		}
			}
			stackpointer = radius;

			for (x = 0; x < w; x++) {

				r[yi] = dv[rsum];
				g[yi] = dv[gsum];
				b[yi] = dv[bsum];

				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;

				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];

				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];

				if (y == 0) {
					vmin[x] = Math.min(x + radius + 1, wm);
				}
				p = pix[yw + vmin[x]];

				sir[0] = (p & 0xff0000) >> 16;
			sir[1] = (p & 0x00ff00) >> 8;
			sir[2] = (p & 0x0000ff);

			rinsum += sir[0];
			ginsum += sir[1];
			binsum += sir[2];

			rsum += rinsum;
			gsum += ginsum;
			bsum += binsum;

			stackpointer = (stackpointer + 1) % div;
			sir = stack[(stackpointer) % div];

			routsum += sir[0];
			goutsum += sir[1];
			boutsum += sir[2];

			rinsum -= sir[0];
			ginsum -= sir[1];
			binsum -= sir[2];

			yi++;
			}
			yw += w;
		}
		for (x = 0; x < w; x++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			yp = -radius * w;
			for (i = -radius; i <= radius; i++) {
				yi = Math.max(0, yp) + x;

				sir = stack[i + radius];

				sir[0] = r[yi];
				sir[1] = g[yi];
				sir[2] = b[yi];

				rbs = r1 - Math.abs(i);

				rsum += r[yi] * rbs;
				gsum += g[yi] * rbs;
				bsum += b[yi] * rbs;

				if (i > 0) {
					rinsum += sir[0];
					ginsum += sir[1];
					binsum += sir[2];
				} else {
					routsum += sir[0];
					goutsum += sir[1];
					boutsum += sir[2];
				}

				if (i < hm) {
					yp += w;
				}
			}
			yi = x;
			stackpointer = radius;
			for (y = 0; y < h; y++) {
				// Preserve alpha channel: ( 0xff000000 & pix[yi] )
				pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;

				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];

				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];

				if (x == 0) {
					vmin[y] = Math.min(y + r1, hm) * w;
				}
				p = x + vmin[y];

				sir[0] = r[p];
				sir[1] = g[p];
				sir[2] = b[p];

				rinsum += sir[0];
				ginsum += sir[1];
				binsum += sir[2];

				rsum += rinsum;
				gsum += ginsum;
				bsum += binsum;

				stackpointer = (stackpointer + 1) % div;
				sir = stack[stackpointer];

				routsum += sir[0];
				goutsum += sir[1];
				boutsum += sir[2];

				rinsum -= sir[0];
				ginsum -= sir[1];
				binsum -= sir[2];

				yi += w;
			}
		}

		bitmap.setPixels(pix, 0, w, 0, 0, w, h);
		return (bitmap);
	}
}
